package com.acwebsitedesign.uRateDrugs.domain;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.stereotype.Component;

import com.acwebsitedesign.uRateDrugs.util.DbUtils;

@Component("UserRepository")
public class AccountRepositoryImpl implements AccountRepository {
	private SimpleJdbcTemplate simpleJdbcTemplate = DbUtils
			.getSimpleJdbcTemplate();

	@Autowired
	private JdbcUserDetailsManager jdbcUserDetailsManager;

	@SuppressWarnings("unchecked")
	public Account getUserById(int id) {
		String sql = "SELECT id, username, password, email, zip, age, gender FROM user where id=?";
		List<Account> userList = simpleJdbcTemplate.query(sql,
				new AccountMapper(), id);
		return userList.get(0);
	}

	@SuppressWarnings("unchecked")
	public Account getUserByUsername(String username) {
		String sql = "SELECT id, username, password, email, zip, age, gender FROM user where username=?";
		List<Account> userList = simpleJdbcTemplate.query(sql,
				new AccountMapper(), username);
		return userList.get(0);
	}

	public void save(Account account) {
		if (account.getId() == 0) {
			insert(account);
		} else {
			update(account);
		}
	}

	public void insert(Account account) {
		String sql = "INSERT INTO user (username, password, email, zip, age, gender) VALUES (?, ?, ?, ?, ?, ?)";
		simpleJdbcTemplate.update(sql, account.getUsername(), account
				.getPassword(), account.getEmail(), account.getZip(), account
				.getAge(), account.isGender());

		// insert username and password in USERS
		String encryptedPassword = new Md5PasswordEncoder().encodePassword(
				account.getPassword(), null);
		User user = new User(account.getUsername(), encryptedPassword, true,
				true, true, true, new ArrayList<GrantedAuthority>());
		jdbcUserDetailsManager.createUser(user);
		jdbcUserDetailsManager.addUserToGroup(user.getUsername(), "GROUP_USER");

	}

	public void update(Account account) {
		String sql = "update user set id=? username=?, password=?, email=?, zip=?, age=?, gender=?) where id=?";
		simpleJdbcTemplate.update(sql, account.getId(), account.getUsername(),
				account.getPassword(), account.getEmail(), account.getZip(),
				account.getAge(), account.isGender());

		// update username and password on USERS
		String encryptedPassword = new Md5PasswordEncoder().encodePassword(
				account.getPassword(), null);
		String username = account.getUsername();
		String userSql = "update users set password=? where username=?";
		simpleJdbcTemplate.update(userSql, encryptedPassword, username);
	}

	public void removeUserByName(String username) {
		String sql = "DELETE FROM user WHERE username=?";
		simpleJdbcTemplate.update(sql, username);

		String sql2 = "delete from users where username=?";
		simpleJdbcTemplate.update(sql2, username);
	}

	@SuppressWarnings("unchecked")
	public boolean isUsernameAvailable(String username) {
		boolean available = true;

		String sql = "SELECT id, username, password, email, zip, age, gender FROM user where username=?";
		List<Account> userList = simpleJdbcTemplate.query(sql,
				new AccountMapper(), username);
		if (!(userList.isEmpty())) {
			available = false;
		}
		
		return available;
	}

	@SuppressWarnings("unchecked")
	private static final class AccountMapper implements RowMapper {
		public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
			int id = rs.getInt("id");
			String username = rs.getString("username");
			String password = rs.getString("password");
			String email = rs.getString("email");
			int zip = rs.getInt("zip");
			int age = rs.getInt("age");
			boolean gender = rs.getBoolean("gender");

			Account account = new Account(id, username, password, email, zip,
					age, gender);
			return account;

		}
	}

}
